Skip to content

refactor(spec)!: retire ActionDescriptor.isAsync (#6748) and correct supportsPause's TSDoc (#6749) - #6862

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-6748-retire-isasync
Aug 9, 2026
Merged

refactor(spec)!: retire ActionDescriptor.isAsync (#6748) and correct supportsPause's TSDoc (#6749)#6862
os-zhuang merged 2 commits into
mainfrom
claude/issue-6748-retire-isasync

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #6748
Fixes #6749

Two cards on one file (packages/spec/src/automation/node-executor.zod.ts), folded into one PR per #6749's own sanctioned option and the claim comments on both issues. They are the two halves of one fact: supportsPause and isAsync were two spellings of "this node type can suspend the run", and #6667 / PR #6746 split them by evidence — supportsPause took the enforce leg, so isAsync takes the remove leg, and supportsPause's own docblock has to stop saying nothing reads it.


Premise verification (both cards verified against origin/main before any edit)

Base: origin/main at 578bdef (the issues were filed against cfeb9a0).

#6748 — the zero-reader measurement, re-run fresh at pickup. All commands run in the worktree at 578bdef:

command result
git grep -nE '\.isAsync' (property reads, objectstack) 0
git grep -nE "\[['\"]isAsync|\"isAsync\"|'isAsync'" (bracket / string access) 0
git grep -nE "\{[^}]*\bisAsync\b[^}]*\}\s*=" (destructuring) 0
git grep -ni isasync — objectui @ origin/main 0
git grep -ni isasync — cloud @ origin/main 0
git grep -n isAsync — objectstack, all forms 22 (was 19 at filing)

The 22 are all non-readers, matching the issue's inventory: 1 declaration, 3 generated baselines, 5 shipped writers, 5 fixtures/shape pins, 8 prose (mdx + four ADRs + one code comment). The count moved 19 → 22 only because the issue's third row counted an org-wide code-search page; the read count is unchanged at zero. Premise holds: no reader appeared since filing.

#6749 — both halves confirmed. The old sentence was still on main verbatim ("A declaration, not an enforced fact (#5703). No execution path reads it…"), and PR #6746's enforcement is on main: AutomationEngine.refuseUndeclaredSuspension plus its call site in executeNode, with supports-pause-runtime-enforcement.test.ts alongside it.


Card 1 — #6748: retire ActionDescriptor.isAsync

Route per the spec-property-retirement skill: retiredKey() tombstone, because ActionDescriptorSchema is z.object({…}).describe(…) and not .strict() — a plain delete would let the five shipped descriptors (and every third-party one) parse clean and lose the key in silence, the ADR-0104 shape.

  • SchemaisAsync: retiredKey(…) with the prescription naming the live two-part mechanism (suspend: true from execute() plus supportsPause: true and a resumeAuthority), and an in-schema comment recording why it is tombstoned rather than deleted.
  • ADR-0087 registration'automation/ActionDescriptor:isAsync' added to RETIRED_KEYS_BY_MAJOR[17] (the exact defKey:name gate (b) reads by set membership), plus a D3 SemanticMigration action-descriptor-is-async-retired in MIGRATIONS_BY_MAJOR[17].semantic, and that step's rationale extended.
  • No D2 MetadataConversion, deliberately — a descriptor is published from an executor's TypeScript (registerNodeExecutor / defineActionDescriptor), never stored in stack metadata; there is no collection for os migrate meta to rewrite. This is the skill's "response-surface key with no source to rewrite" case, the EnhancedApiError.fieldErrors disposition one layer down.
  • Liveness ledger — no row to advance, and that is the correct reading, not an omission. See the dedicated section below.
  • The five shipped writers stop writing itbuiltin/screen-nodes.ts, builtin/map-node.ts, builtin/wait-node.ts, plugin-approvals/approval-node.ts, plugin-approvals/approval-revise-node.ts, each leaving a one-line marker where the key was.
  • Fixtures triaged individually, not batch-deleted — four were shape pins that merely carried the key (dropped), and approval-revise.test.ts pinned exactly the deleted limb inside a toMatchObject, which would have gone on passing if the key ever came back. Replaced with an explicit expect(descriptor).not.toHaveProperty('isAsync'), so the retirement has a pin that can actually go red.
  • Pin tests (packages/spec/src/automation/node-executor.test.ts) — the prescription is asserted (.toThrow(/ActionDescriptor\.isAsync.*removed.*supportsPause: true/s)), isAsync: false is asserted to be refused too (the realistic upgrade shape: someone who spelled out the old default must not slip through), and a clean parse is asserted to publish no isAsync of its own.
  • Generated baselinesauthorable-surface/automation.json gains automation/ActionDescriptor:isAsync [RETIRED]; authorable-defaults/automation.json loses its = false default line. Both produced by gen:schema, never hand-edited.
  • Regeneratedgen:spec-changes, gen:upgrade-guide, gen:api-surface, gen:docs.
  • Changesetmajor for @objectstack/spec with the FROM → TO mapping; patch for @objectstack/service-automation and @objectstack/plugin-approvals, whose published descriptors lose the key.
  • Forms / skills / examples: nothing to prune — verified by grep: no *.form.ts input, no skills/** mention, no examples/** author site. So no i18n:extract delta either (check:i18n green).
  • ADRs left as written. docs/adr/0018, 0019, 0044 mention isAsync as the decision they made at the time; an ADR is a record, not a reference page, and the repo's precedent is that retired keys survive in ADR prose (triggerPhrases still sits in ADR-0010 after its retirement). The one non-ADR code comment that called the isAsync variant future work (builtin/http-nodes.ts) was corrected, since it addresses whoever implements that variant next.

The four ratchets — expected readings for THIS route

The skill warns that the expected reading depends on the route, so stating it before the numbers: this is a key tombstone, neither an enum-value narrowing nor a whole-def deletion. So authorable-surface/ must move (it does — the [RETIRED] mark) and authorable-defaults/ must lose the default line (it does), while api-surface/ and json-schema.manifest/ must not: the def is still emitted, no exported schema died with the key, and api-surface prints type references and is structurally blind to key-level narrowing. Measured: both unchanged. authorable-surface.base.json is likewise untouched — it is the merge-base snapshot the live → retired transition is judged against, which is exactly how gate (b) saw this removal at all.


Card 2 — #6749: correct supportsPause's TSDoc

Comment-only, as specified. The corrected block states the boundary #6746 drew, in the issue's own three parts:

Plus the alias hop, since the descriptor consulted is the canonical one an ADR-0018 alias forwards to.

Does the docblock project into generated references? Asked and answered by measurement rather than assumed: no. gen:docs renders .describe(), not the TSDoc, and the only line this PR moves in content/docs/references/automation/node-executor.mdx is the isAsync row from card 1. supportsPause's row is byte-identical.


The liveness ledger question, answered explicitly

The dispatch expected an isAsync row whose verdict needed advancing. There is none, and there should not be. packages/spec/liveness/ is keyed by metadata typeaction.json is ActionSchema (ui/action.zod.ts, what an author writes in a stack), not automation/ActionDescriptor (what an executor publishes at registration). grep -rn isAsync packages/spec/liveness/ returns nothing, and no ledger file covers ActionDescriptor at all.

That makes this the skill's strict-removal-style ledger discipline by a different road: there is no row to keep and none to delete, so check:liveness has nothing to say either way — and it passes, rather than reporting the key UNCLASSIFIED (which is what would happen if ActionDescriptor were in the walk and I had deleted a row). No ledger file, and no liveness/README.md count, is touched by this PR.


Reverse verification — direction predicted BEFORE running

Predicted: RED, the usual direction. The key sits in no ?? chain and the pins judge a rejection the schema owns by name, so no inversion was available. Restoring the deleted limb (isAsync: z.boolean().default(false)) had to fail all three new pins: isAsync: true would parse instead of throwing, isAsync: false likewise, and .default(false) would put the key back on the parsed object so not.toHaveProperty('isAsync') fails.

Measured, with the limb restored (git checkout origin/main -- …, never git stashrefs/stash is shared by every worktree of this repo):

Test Files  2 failed | 344 passed (346)
     Tests  53 failed | 8827 passed (8880)

versus the committed tree:

Test Files  346 passed (346)
     Tests  8880 passed (8880)

Red as predicted, and wider than predicted in an informative way: the second failing file is a generated-baseline pin, so the [RETIRED] baseline line is independently load-bearing rather than decorative.

One honest note on method, because it changed the sequencing of this PR: the restore step was written as git checkout BRANCH -- PATH, which reads the branch tip commit — and at that moment nothing had been committed yet, so the branch tip was origin/main and the "restore" silently re-applied the revert. The two files were rewritten from the transcript, and the work is now committed before any revert experiment. Recorded because the skill's restore recipe presumes a commit exists and does not say so.

Tests and gates

Every build/test run serialized on the shared verification lock (flock), heap capped, test parallelism capped.

  • @objectstack/spectsc --noEmit pass, test 346 files / 8880 tests, all pass. Worth naming: the tombstone types the key never, so the typecheck is also the sweep proving no authoring site in the package survived.
  • @objectstack/service-automation71 files / 868 tests pass. @objectstack/plugin-approvals19 files / 446 tests pass. @objectstack/dogfood — pass (in a retirement's default consumption radius per the skill, whatever the import graph says).
  • The gate list enumerated from .github/workflows/lint.yml, run one by one: the spec-scoped set (check:authorable-surface, check:generated --reconcile-only, check:docs, check:spec-changes, check:upgrade-guide, check:api-surface, check:skill-refs / -docs / -examples, check:react-blocks, check:dual-source-exports, check:exported-any), plus check:liveness, check:empty-state, check:variant-docs (the three the skill flags as having no generator, so a red there is a real finding), the ~40 root check:* gates, check:doc-formula-expressions, the downstream-contract typecheck, and pnpm lint. All green.

Two results that needed adjudicating rather than assuming, both recorded:

  1. The first sweep had 9 reds; all 9 were one cause — the unbuilt workspace closure in a fresh worktree (Cannot find module '@objectstack/core', Failed to resolve entry for package "@objectstack/formula"). Three of those gates diagnose it themselves in so many words: "PREREQUISITE NOT MET — the workspace packages are not built … Nothing was measured." Building the closure exactly as lint.yml does (turbo run build --filter='./packages/*' --filter='./packages/*/*', 70/70 successful) turned all nine green. This is the skill's stale-dist trap, and it is why none of them was read as a finding.
  2. A bare tsc --noEmit on service-automation reports 3 errors — pre-existing, and CI does not run that command. The package has no typecheck script, so turbo run typecheck skips it; it is governed instead by the DEBT ledger, whose entry records errors: 5 and whose note names these three verbatim: "3 are TS2341 in src/nested-region-parity.test.ts, where the tests dot-read the private engine.flows". That file is untouched by this PR. The governing gate, check:type-check-debt, passes — "34 ledger entr(ies) re-measured … none above its recorded number". This PR sits at 3 against a ceiling of 5, so it lowers rather than raises, and no note rewrite is owed.

check:resume-authority-declared deserves a specific mention: it keys on supportsPause: true, never on isAsync, so removing the key cannot move it. It stays green — and its own output now reads "A suspension from a type that declares supportsPause: false is refused by the engine at run time (#6667), not by this gate", which is the evidence for the claim rather than an assertion of it.


Scope

No supportsPause behaviour changed anywhere — #6749 is comment-only and #6746's engine seam is untouched. packages/spec/src/data/hook.zod.ts's isasync is a data-hook tombstone alias mapping to async, a different key with a similar name, and is deliberately not touched.

One out-of-scope finding filed, not fixed here: #6844 — the same #6746 residue in the D3 ledger's resume-authority-undeclared… acceptanceCriteria, which still tells upgraders that supportsPause is enforced by nothing and to hand-audit the mismatch. That string projects verbatim into spec-changes.json and docs/protocol-upgrade-guide.md, so correcting it has a generated-artifact consequence #6749 explicitly disclaimed.


Generated by Claude Code

…supportsPause's TSDoc (#6749)

`ActionDescriptor.isAsync` was a second spelling of `supportsPause` that no
execution path read — verified zero readers across objectstack, objectui and
cloud at pickup. Its sibling took the enforce leg of ADR-0049 in #6667/PR #6746;
this one takes the remove leg.

Tombstoned via retiredKey() rather than deleted (ActionDescriptorSchema is not
.strict(), so a plain delete would silently strip the key). Registered by exact
key in RETIRED_KEYS_BY_MAJOR[17] plus an ADR-0087 D3 SemanticMigration — no D2
conversion, because a descriptor is published from executor TypeScript and never
stored in stack metadata, so there is no source for `os migrate meta` to rewrite.
The five shipped writers stop writing it; generated baselines, spec-changes, the
upgrade guide and reference docs regenerated.

Also corrects supportsPause's TSDoc, which still described itself as a
declaration no execution path reads — false since #6746 (#6749). Comment-only;
no schema, baseline or behaviour change on that key.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011sGk4SKHqGRgmmqUok1P8M
@vercel

vercel Bot commented Aug 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 9, 2026 1:39am

Request Review

@github-actions github-actions Bot added the size/m label Aug 9, 2026
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/plugin-approvals, @objectstack/service-automation, @objectstack/spec.

112 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/plugin-approvals, @objectstack/spec)
  • content/docs/automation/connectors.mdx (via @objectstack/spec)
  • content/docs/automation/flows.mdx (via @objectstack/service-automation, @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/cli.mdx (via @objectstack/spec)
  • content/docs/deployment/tenancy-modes.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via @objectstack/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/data-service.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via @objectstack/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/plugin-approvals, @objectstack/service-automation, @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/spec)
  • content/docs/permissions/authorization.mdx (via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/rls.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/plugin-approvals, @objectstack/service-automation, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/plugin-approvals, @objectstack/service-automation, @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/spec)
  • content/docs/releases/v17.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/plugin-approvals, @objectstack/service-automation, @objectstack/spec)
  • content/docs/ui/actions.mdx (via @objectstack/spec)
  • content/docs/ui/apps.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/field-grouping-and-order.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)
  • content/docs/ui/translations.mdx (via @objectstack/spec)
  • content/docs/ui/views.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling labels Aug 9, 2026
…irement (#6148 gate)

The changeset declares a breaking change (major + bang), so
check-adr-0087-registration requires the ledger question to be answered in
writing. It IS registered: the D3 SemanticMigration
`action-descriptor-is-async-retired` plus the exact-key
RETIRED_KEYS_BY_MAJOR[17] entry both land in this PR.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011sGk4SKHqGRgmmqUok1P8M
@os-zhuang
os-zhuang marked this pull request as ready for review August 9, 2026 02:01
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 9, 2026
Merged via the queue into main with commit e5bd768 Aug 9, 2026
26 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-6748-retire-isasync branch August 9, 2026 02:22
os-zhuang pushed a commit that referenced this pull request Aug 9, 2026
`main` gained #6868 (`page-tabs-type-to-tab-style` + `ui/PageTabsProps:type`)
after this branch's last CI head. The merge itself was clean — git placed the
three siblings' entries at different offsets — but the generated artifacts are
driver-deferred and were regenerated from the merged tree rather than
text-merged.

All three protocol-17 siblings verified present after regeneration:
`notification-list-cursor-retired` (this PR), `action-descriptor-is-async-retired`
(#6862) and `page-tabs-type-to-tab-style` (#6868, a D2 conversion).

`authorable-surface/api.json` and `authorable-defaults/api.json` pick up
`api/ApiRoutes:email` and `api/MetadataEndpointsConfig:maskObjectFields` from
other PRs merged in the same window — this branch's copies were simply behind.

check:generated 10/10.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011sGk4SKHqGRgmmqUok1P8M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

2 participants